import { PenChildProps, PenEventProps } from "@/types";
import { Button, Collapse, Input, Select, Space } from "antd";
import { useState } from "react";
import { deepClone, EventAction } from "@meta2d/core";
import { Event } from "@meta2d/core/src/event/event";
import { FormRowCol } from "@/components/common/FormRowCol.tsx";
import { DeleteOutlined } from "@ant-design/icons";
import { EventLink } from "@/components/Configuration/PenProps/components/EventLink.tsx";
import { EventSetProps } from "@/components/Configuration/PenProps/components/EventSetProps.tsx";
import { ReactAceEditor } from "@/components/common/ReactAceEditor.tsx";
import { EventSetTarget } from "@/components/Configuration/PenProps/components/EventSetTarget.tsx";
import { EventExecuteJs } from "@/components/Configuration/PenProps/components/EventExecuteJs.tsx";
import { EventExecuteGlobalFn } from "@/components/Configuration/PenProps/components/EventExecuteGlobalFn.tsx";
import { EventEmit } from "@/components/Configuration/PenProps/components/EventEmit.tsx";

function Main(props: PenEventProps) {
  let { item, onChange, index } = props;
  const [showCodeEditor, setShowCodeEditor] = useState(false);
  const reset = () => {
    item.value = undefined;
    item.params = undefined;
    item.where = { type: undefined };
    onChange("params", undefined, index);
    onChange("value", undefined, index);
    onChange("where", { type: undefined }, index);
  };
  const showEventSetTarget = (action: EventAction) => {
    let arr = [
      EventAction.StartAnimate,
      EventAction.PauseAnimate,
      EventAction.StopAnimate,
      EventAction.StartVideo,
      EventAction.PauseVideo,
      EventAction.StopVideo,
    ];
    return arr.includes(action);
  };
  return (
    <>
      <Space
        style={{ padding: "10px" }}
        className={"w-full"}
        direction="vertical"
      >
        <FormRowCol label="事件类型">
          <Select
            className={"w-full"}
            value={item.name}
            options={[
              { label: "单击", value: "click" },
              { label: "双击", value: "dblclick" },
              { label: "鼠标按下", value: "mousedown" },
              { label: "鼠标抬起", value: "mouseup" },
              { label: "鼠标进入", value: "enter" },
              { label: "鼠标离开", value: "leave" },
              { label: "选中", value: "active" },
              { label: "取消选中", value: "inactive" },
              { label: "值变化", value: "valueUpdate" },
            ]}
            onSelect={(value) => {
              onChange("name", value, index);
            }}
          />
        </FormRowCol>
        <FormRowCol label="事件行为">
          <Select
            className={"w-full"}
            value={item.action}
            options={[
              { label: "打开链接", value: EventAction.Link },
              { label: "更改属性", value: EventAction.SetProps },
              { label: "执行动画", value: EventAction.StartAnimate },
              { label: "暂停动画", value: EventAction.PauseAnimate },
              { label: "停止动画", value: EventAction.StopAnimate },
              { label: "执行JS代码", value: EventAction.JS },
              { label: "执行全局函数", value: EventAction.GlobalFn },
              { label: "发送消息", value: EventAction.Emit },
              { label: "播放视频", value: EventAction.StartVideo },
              { label: "暂停视频", value: EventAction.PauseVideo },
              { label: "停止视频", value: EventAction.StopVideo },
              { label: "发送图元数据", value: EventAction.SendPropData },
              { label: "发送绑定变量", value: EventAction.SendVarData },
            ]}
            onSelect={(value) => {
              onChange("action", value, index);
            }}
            onChange={() => {
              reset();
            }}
          />
        </FormRowCol>
        {item.action == EventAction.Link && <EventLink {...props} />}
        {item.action == EventAction.SetProps && <EventSetProps {...props} />}
        {item.action == EventAction.JS && <EventExecuteJs {...props} />}
        {item.action == EventAction.GlobalFn && (
          <EventExecuteGlobalFn {...props} />
        )}
        {item.action == EventAction.Emit && <EventEmit {...props} />}
        {(item.action == EventAction.SendPropData ||
          item.action == EventAction.SendVarData) && (
          <>
            <EventSetProps {...props} />
            <FormRowCol label={"Topics*"} illustrate={"仅针对mqtt通信"}>
              <Input
                value={props.item.extend}
                onChange={(e) => {
                  props.onChange("extend", e.target.value, props.index);
                }}
              />
            </FormRowCol>
          </>
        )}
        {showEventSetTarget(item.action) && <EventSetTarget {...props} />}
        <FormRowCol label="触发条件">
          <Select
            className={"w-full"}
            value={item.where?.type ?? ""}
            options={[
              { label: "无", value: "" },
              { label: "关系运算", value: "comparison" },
              { label: "自定义代码", value: "fn" },
            ]}
            onSelect={(value) => {
              if (value == "") {
                onChange("where", { type: undefined }, index);
              }
              onChange(
                "where",
                {
                  ...item.where,
                  type: value,
                },
                index,
              );
            }}
          />
        </FormRowCol>
        {item.where?.type == "comparison" && (
          <>
            <FormRowCol label="属性名">
              <Input
                placeholder={"key"}
                value={item.where?.key}
                onChange={(e) => {
                  onChange(
                    "where",
                    {
                      ...item.where,
                      key: e.target.value,
                    },
                    index,
                  );
                }}
              />
            </FormRowCol>
            <FormRowCol label="条件">
              <Select
                className={"w-full"}
                value={item.where?.comparison}
                options={[
                  { label: "大于", value: ">" },
                  { label: "大于等于", value: ">=" },
                  { label: "小于", value: "<" },
                  { label: "小于等于", value: "<=" },
                  { label: "等于", value: "=" },
                  { label: "不等于", value: "!=" },
                  { label: "介于", value: "[)" },
                  { label: "不介于", value: "![)" },
                  { label: "属于", value: "[]" },
                  { label: "不属于", value: "![]" },
                ]}
                onSelect={(value) => {
                  onChange(
                    "where",
                    {
                      ...item.where,
                      comparison: value,
                    },
                    index,
                  );
                }}
              />
            </FormRowCol>
            <FormRowCol label="属性值">
              <Input
                placeholder={"value"}
                value={
                  typeof item.where?.value == "string" ? item.where?.value : ""
                }
                onChange={(e) => {
                  onChange(
                    "where",
                    {
                      ...item.where,
                      value: e.target.value,
                    },
                    index,
                  );
                }}
              />
            </FormRowCol>
          </>
        )}
        {item.where?.type == "fn" && (
          <>
            <FormRowCol label={"高优先级判断"}>
              <Button onClick={() => setShowCodeEditor(true)}>编 辑</Button>
            </FormRowCol>
            <ReactAceEditor
              open={showCodeEditor}
              tip={
                " 可获取pen和context参数,返回值为Boolean类型，例如：console.log(pen,context);return true;"
              }
              onOk={(code) => {
                setShowCodeEditor(false);
                onChange(
                  "where",
                  {
                    ...item.where,
                    fnJs: code,
                  },
                  index,
                );
              }}
              onCancel={() => setShowCodeEditor(false)}
              value={item.where.fnJs || ""}
            ></ReactAceEditor>
          </>
        )}
      </Space>
    </>
  );
}

function PenEventItem(props: PenEventProps) {
  return (
    <>
      <Collapse
        style={{ border: "none", borderRadius: 0, borderColor: "#000000" }}
        items={[
          {
            key: "Collapse",
            label: (
              <div className={"flex between"}>
                <span>事件{props.index + 1}</span>

                <DeleteOutlined
                  onClick={(event) => {
                    event.stopPropagation();
                    props.remove(props.index);
                  }}
                />
              </div>
            ),
            children: <Main {...props} />,
            style: {
              borderRadius: 0,
              borderColor: "#000000",
            },
          },
        ]}
        defaultActiveKey={["Collapse"]}
      />
    </>
  );
}

export function PenEvents({ penOptions, setPenValue }: PenChildProps) {
  const handleAdd = () => {
    setPenValue("events", [
      ...(penOptions.events || []),
      {
        name: undefined,
        action: undefined,
        where: {
          type: undefined,
        },
      },
    ]);
  };
  const handleRemove = (index: number) => {
    let newEventList = deepClone(penOptions.events || []);
    newEventList.splice(index, 1);
    setPenValue("events", newEventList);
  };
  const onValueChange = (key: keyof Event, value: any, index: number) => {
    let newEventList = deepClone(penOptions.events || []);
    if (newEventList[index]) {
      let item = newEventList[index];
      item[key] = value as never;
      setPenValue("events", newEventList);
    }
  };
  return (
    <>
      <div style={{ padding: 10 }}>
        <Button block type={"primary"} onClick={handleAdd}>
          添加事件{" "}
          {penOptions.events && penOptions.events.length > 0 && (
            <>({penOptions.events.length}个)</>
          )}
        </Button>
      </div>
      {penOptions.events &&
        penOptions.events.map((item, index) => (
          <PenEventItem
            item={item}
            remove={handleRemove}
            onChange={onValueChange}
            key={`eventItem${index}`}
            index={index}
          ></PenEventItem>
        ))}
    </>
  );
}
